package com.se.nused;

import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;

/**
 * Created by hdu_huang on 2018/12/27.
 */
@Slf4j
public class PECSTest {

    /**
    * @author hdu_huang
    * @date   2018/12/27
    * @desc   PECS 原则 [如果从集合读则extend,写则super, 既读又写 则不变]
     *  一般泛型出现在参数则Consumer Super 返回值 Producer Extends
     *  出现参数和返回值则不变
     *   <? extend Fruit> extend上界 Fruit的任意子类但是不能确定，因此无法添加元素，只能迭代
     *   <? super Apple>  super 下界  只能添加元素，迭代为 Object
     *   <?> 实参无法添加，迭代{Object}
    */
    public static void main(String[] args) {

        //不能用 ? extend String
        Consumer<? super String> consumer = s -> log.info(s);

        consumer.accept("hello");

        // ? 相当于 Object，不能添加元素 迭代时Object
        List<?> list = new ArrayList<>(List.of("Hello", "world"));
//        list.add("Hello"); //error


        //也不能添加元素 生产者 轻松地迭代元素
        List<? extends String> list1 = new ArrayList<>(List.of("Hello", "world"));
//        list1.add("Hello"); //error

        //可以添加元素 消费者 迭代时Object
        List<? super String> list2 = new ArrayList<>(List.of("Hello", "world"));
        list2.add("Hello"); //error


        //PECS
        //Collections.copy();


        // n <= m => f(n) <= f(m) 协变(covariant) | contravariant
        // Java 数组协变[但执行严格的运行类型和长度检查], 数组元素无volatile, final 语义

        Object[] objs = new String[3];
        objs[0] = "String";
//        objs[1] = 1; // ArrayStoreException

        System.out.println(objs[0]);
    }
}
